Projet 14 - Script de base d'installation d'un serveur Ubuntu LTS

Date de création de cette note : 2024-10-11.

Quel est l'objectif de ce projet ?

Je souhaite implémenter et publier un projet de "référence", de type skeleton, dont la fonction est d'installer les éléments de base d'un serveur Ubuntu LTS sécurisé.

Comme point de départ, je peux utiliser mon repository poc-bash-ssh-docker-deployement-example et le faire évoluer.

Le script _install_basic_server_configuration.sh se contente d'installer Docker.

J'aimerais y intégrer les recommandations présentes dans l'excellent article "Securing A Linux Server".

J'aimerais, entre autres, ajouter les fonctionnalités suivantes :

  • [x] Amélioration de la configuration de OpenSSH ;
  • [x] Installation et configuration de ufw ;
  • [x] Mise en place de ipsum ;
  • [x] Installation et configuration de fail2ban ;
  • [x] Système d'installation / suppression de clés ssh ;
  • [x] En option : installation et configuration de node exporter ;
  • [x] En option : installation et configuration de l'envoi des logs de journald et Docker vers Loki en utilisatant Promtail (installation et configuration de l'envoi des logs de journald vers Loki en utilisant Vector) ;
  • [x] En option : installation de configuration de Grafana ; avec Grizzly configuration des dashboards
    • [x] des logs et
    • [x] metrics des serveurs
  • [x] En option : installer et configurer apticron pour envoyer un message dans les logs dès qu'un package de sécurité doit être installé.
    • [x] Génération d'une alerte Grafana si une mise à jour de sécurité doit être installé
  • [x] En option : envoie de notification sur smartphone en cas d'alerte Grafana, via ntfy
  • [ ] En option : installation et configuration de Linux Audit ;

Le repository doit présenter cette installation :

Repository de ce projet :

Ressources :


Journaux liées à cette note :

Journal du dimanche 20 octobre 2024 à 22:50 #vagrant, #dns, #coding, #iteration

Nouvelle #iteration du Projet 14 - Script de base d'installation d'un serveur Ubuntu LTS.

Il y a quelques jours, j'ai migré de vagrant-hostmanger vers vagrant-dns. J'ai ensuite souhaité mettre en œuvre Grizzly, mais j'ai rencontré un problème.

J'ai installé une version binaire statiquement liée de Grizzly à l'aide de Mise. Dans cette version, Go ne fait pas appel à la fonction getaddrinfo pour la résolution des noms d'hôte. Au lieu de cela, Go se limite à lire les informations de configuration DNS dans /etc/resolv.conf (champ nameserver) et les entrées de /etc/hosts.

Cela signifie que les serveurs DNS gérés par systemd-resolved ne sont pas pris en compte 😭.

Pour régler ce problème, j'utilise en même temps vagrant-dns et Vagrant Host Manager : voici le commit.

J'active uniquement ici le paramètre config.hostmanager.manage_host = true et je laisse vagrant-dns résoudre les hostnames à l'intérieur des machines virtuelles et des containers Docker.

Journal du vendredi 18 octobre 2024 à 22:51 #grafana, #DevOps, #InfrastructureAsCode, #JaiDécouvert

En cherchant un outil d'Infrastructure as code pour Grafana, #JaiDécouvert Grizzly.

Un projet qui a débuté en mars 2020, développé en Go par l'équipe de Grafana.

A utility for managing Jsonnet dashboards against the Grafana API

J'ai parcouru l'intégralité de la documentation et je suis ravi, ce projet correspond parfaitement à ce que je cherchais depuis des années !

Avant de découvrir cet outil, j'écrivais des scripts Python ou Bash d'exportation et d'importation de dashboards via l'API de Grafana.

Je souhaite l'utiliser dans le Projet 14 - Script de base d'installation d'un serveur Ubuntu LTS. Dans le repository basic_ubuntu_server_install_playground.

Journal du vendredi 18 octobre 2024 à 19:15 #DevOps, #admin-sys, #vagrant, #dns, #difficulté, #iteration, #file

Nouvelle #iteration de Projet 14.

Pour traiter ce problème, je souhaite essayer de remplacer Vagrant Host Manager par vagrant-dns.

-- from

Résultat : j'ai migré de Vagrant Host Manager vers vagrant-dns avec succès 🙂.

Voici le commit : lien vers le commit.

Voici quelques explications de la configuration Vagrantfile.

Les lignes suivantes permettent d'utiliser la seconde IP des machines virtuelles pour identifier les identifier (renseignés par le serveur DNS).

  config.dns.ip = -> (vm, opts) do
    ip = nil
    vm.communicate.execute("hostname -I | cut -d ' ' -f 2") do |type, data|
      ip = data.strip if type == :stdout
    end
    ip
  end

La commande hostname retourne les deux IP de la machine virtuelle :

vagrant@server1:~$ hostname -I
10.0.2.15 192.168.56.22

La commande hostname -I | cut -d ' ' -f 2 capture la seconde IP, ici 192.168.56.22.

La configuration DNS qui retourne cette IP est consultable via :

$ vagrant dns -l
/server1.vagrant.test/ => 192.168.56.22
/server2.vagrant.test/ => 192.168.56.23
/grafana.vagrant.test/ => 192.168.56.23
/loki.vagrant.test/ => 192.168.56.23

Autre subtilité :

vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]

Cette ligne configure la machine virtuelle pour qu'elle utilise le serveur DNS de vagrant-dns.
Cela permet de résoudre les noms des autres machines virtuelles. Exemple :

vagrant@server1:~$ resolvectl query server2.vagrant.test
server2.vagrant.test: 192.168.56.23            -- link: eth0

-- Information acquired via protocol DNS in 12.3ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

En mettant en place vagrant-dns sur ma workstation qui tourne sous Fedora, j'ai rencontré la difficulté suivante.

J'avais la configuration suivante installée :

$ cat /etc/systemd/resolved.conf.d/csd.conf
[Resolve]
DNS=10.57.40.1
Domains=~csd

Elle me permet de résoudre les hostnames des machines qui appartiennent à un réseau privé exposé via OpenVPN (voir cette note).

Voici ma configuration complète de systemd-resolved :

$ systemd-analyze cat-config systemd/resolved.conf
# /etc/systemd/resolved.conf

...

[Resolve]
...

# /etc/systemd/resolved.conf.d/1-vagrant-dns.conf
# This file is generated by vagrant-dns
[Resolve]
DNS=127.0.0.1:5300
Domains=~test

# /etc/systemd/resolved.conf.d/csd.conf
[Resolve]
DNS=10.57.40.1
Domains=~csd

Quand je lançais resolvectl query server2.vagrant.test pour la première fois après redémarrage de sudo systemctl restart systemd-resolved, tout fonctionnait correctement :

$ resolvectl query server2.vagrant.test
server2.vagrant.test: 192.168.56.23

-- Information acquired via protocol DNS in 7.5073s.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

Mais, la seconde fois, j'avais l'erreur suivante :

$ resolvectl query server2.vagrant.test
server2.vagrant.test: Name 'server2.vagrant.test' not found

Ce problème disparait si je supprime /etc/systemd/resolved.conf.d/csd.conf.

Je n'ai pas compris pourquoi. D'après la section "Protocols and routing" de systemd-resolved, le serveur 10.57.40.1 est utilisé seulement pour les hostnames qui se terminent par .csd.

J'ai activé les logs de systemd-resolved au niveau debug avec

$ sudo resolvectl log-level debug
$ journalctl -u systemd-resolved -f

Voici le contenu des logs lors de la première exécution de resolvectl query server2.vagrant.test : https://gist.github.com/stephane-klein/506a9fc7d740dc4892e88bfc590bee98.

Voici le contenu des logs lors de la seconde exécution de resolvectl query server2.vagrant.test : https://gist.github.com/stephane-klein/956befc280ef9738bfe48cdf7f5ef930.

J'ai l'impression que la ligne 13 indique que le cache de systemd-resolved a été utilisé et qu'il n'a pas trouvé de réponse pour server2.vagrant.test. Pourquoi ? Je ne sais pas.

Ligne 13 : NXDOMAIN cache hit for server2.vagrant.test IN A

Ensuite, je supprime /etc/systemd/resolved.conf.d/csd.conf :

$ sudo rm /etc/systemd/resolved.conf.d/csd.conf

Je relance systemd-resolved et voici le contenu des logs lors de la seconde exécution de resolvectl query server2.vagrant.test : https://gist.github.com/stephane-klein/9f87050524048ecf9766f9c97b789123#file-systemd-resolved-log-L11

Je constate que cette fois, la ligne 11 contient : Cache miss for server2.vagrant.test IN A.

Pourquoi avec .csd le cache retourne NXDOMAIN et sans .csd, le cache retourne Cache miss et systemd-resolved continue son algorithme de résosultion du hostname ?

Je soupçonne systemd-resolved de stocker en cache la résolution de server2.vagrant.test par le serveur DNS 10.57.40.1. Si c'est le cas, je me demande pourquoi il fait cela alors qu'il est configuré pour les hostnames qui se terminent par .csd 🤔.


Autre problème rencontré, la latence de réponse :

$ resolvectl query server2.vagrant.test
server2.vagrant.test: 192.168.56.23

-- Information acquired via protocol DNS in 7.5073s.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

La réponse est retournée en 7 secondes, ce qui ne me semble pas normal.

J'ai découvert que je n'ai plus aucune latence si je passe le paramètre DNSStubListener à no :

$ sudo cat <<EOF > /etc/systemd/resolved.conf.d/0-vagrant-dns.conf
[Resolve]
DNSStubListener=no
EOF
$ sudo systemctl restart systemd-resolved
$ resolvectl query server2.vagrant.test
server2.vagrant.test: 192.168.56.23

-- Information acquired via protocol DNS in 2.9ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

Le temps de réponse passe de 7.5s à 2.9ms. Je n'ai pas compris la signification de ma modification.


Je récapitule, pour faire fonctionner correctement vagrant-dns sur ma workstation Fedora j'ai dû :

  • supprimer /etc/systemd/resolved.conf.d/csd.conf
  • et paramétrer DNSStubListener à no

Migration de vagrant-hostmanager vers vagrant-dns #DevOps, #admin-sys, #vagrant, #dns

Dans le cadre du Projet 14 - Script de base d'installation d'un serveur Ubuntu LTS, j'utilise Vagrant avec le plugin Vagrant Host Manager pour gérer les hostnames des machines virtuelles.

Vagrant Host Manager met correctement à jour les fichiers /etc/hosts sur ma machine hôte, c'est-à-dire, ma workstation, et dans les machines virtuels.
Cependant, ces noms d'hôtes ne sont pas accessibles à l'intérieur des containers Docker.
Par exemple, ici, http://grafana.example.com:3100/ n'est pas accessible à l'intérieur du container Promtail.

Pour traiter ce problème, je souhaite essayer de remplacer Vagrant Host Manager par vagrant-dns.

vagrant-dns semble exposer un serveur DNS qui sera accessible et utilisé par les containers Docker.

D'autre part, vagrant-dns (page contributors) semble un peu plus actif que Vagrant Host Manager (page contributors).